package de.fhtrier.mp.wollmaus.gamestate;

import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.state.StateBasedGame;
import org.newdawn.slick.state.transition.FadeInTransition;
import org.newdawn.slick.state.transition.FadeOutTransition;
import org.newdawn.slick.state.transition.Transition;

import de.fhtrier.mp.wollmaus.MainGame;
import de.fhtrier.mp.wollmaus.constants.Constants;
import de.fhtrier.mp.wollmaus.entity.Note;
import de.fhtrier.mp.wollmaus.entity.Player;
import de.fhtrier.mp.wollmaus.gamestate.menus.MenuState;
import de.fhtrier.mp.wollmaus.gamestate.menus.WonState;
import de.fhtrier.mp.wollmaus.gui.GUI;
import de.fhtrier.mp.wollmaus.gui.Reset;
import de.fhtrier.mp.wollmaus.map.Hindernis;
import de.fhtrier.mp.wollmaus.map.Stage;
import de.fhtrier.mp.wollmaus.map.StageContainer;
import de.fhtrier.mp.wollmaus.util.AssetManager;

public class GameState extends AbstractState {
	private Player player;
	private Stage stage;

	private static GameState instance;

	private GUI gui;
	private Reset resetGui;

	private boolean startMusicOne;

	public GameState() {
		instance = this;
		
		resetGui = new Reset(this);
	}

	public static GameState getInstance() {
		return instance;
	}

	@Override
	public void init(GameContainer gc, StateBasedGame sbg) throws SlickException {
		stage = StageContainer.getNextStage();

		// Initialisierungen für die Spielfigur
		player = new Player(this);

		gui = new GUI(this);
		resetLevel();
	}

	@Override
	public void enter(GameContainer gc, StateBasedGame sbg) throws SlickException {
		if (startMusicOne == false) {
			MainGame.instance.bgMusic = AssetManager.getInstance().getMusic(AssetManager.MUSIC_LEVEL1);
			MainGame.instance.bgMusic.loop(1f, Constants.MUSIC_VOLUME);
			startMusicOne = true;
		}
	}

	@Override
	public void leave(GameContainer gc, StateBasedGame sbg) throws SlickException {
		stage = StageContainer.getNextStage();
		resetLevel();
	}

	@Override
	public int getID() {
		return 0;
	}

	@Override
	public void render(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException {
		stage.render(gc, g);

		gui.render(gc, g);

		// zeichnet die Hindernisse als Dummys ein
		if (Constants.debug == true) {
			g.setColor(Color.white);
			for (Hindernis h : stage.getHindernisse()) {
				g.fillRect(h.getPunkt().x, h.getPunkt().y, h.getBreite(), h.getHoehe());
			}
		}

		player.render(gc, g);
		if (resetGui.isEnabled()) {
			resetGui.render(gc, g);
		}
	}

	@Override
	public void update(GameContainer gc, StateBasedGame sbg, int delta) throws SlickException {
		super.update(gc, sbg, delta);
		stage.update(gc, delta);
		if (resetGui.isEnabled()) {
			resetGui.update(gc, delta);
		}
		else {
			player.update(gc, delta);
		}
	}

	public void resetLevel() {
		player.respawn();

		for (Note n : stage.getNotes()) {
			n.setCollected(false);
		}
	}

	public void changeLevel() {
		Transition transitionOut = new FadeOutTransition(Color.black, 1000);
		Transition transitionIn = new FadeInTransition(Color.black, 1000);
		if (StageContainer.isLastStage()) {
			MainGame.instance.bgMusic.stop();
			MenuState.instance.setMenuState(new WonState(MenuState.instance));
			MainGame.instance.enterState(1, transitionOut, transitionIn);
		}
		else if (StageContainer.getCurrentStageNumber() == 0) {
			IntroState.instance.preEnter();
			MainGame.instance.enterState(0, transitionOut, transitionIn);
		}
		else { 
			IntroState.instance.preEnter();
			MainGame.instance.enterState(2, transitionOut, transitionIn);
		}
	}

	public Stage getStage() {
		return stage;
	}

	public Player getPlayer() {
		return player;
	}
	
	public Reset getResetGui() {
		return resetGui;
	}

}
